package cn.fzkj.framework.messagequece.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class RabbitConfig {

    private static final Logger log = LoggerFactory.getLogger(RabbitConfig.class);
    @Value("${spring.rabbitmq.host}")
    private String host;
    @Value("${spring.rabbitmq.port}")
    private int port;
    @Value("${spring.rabbitmq.username}")
    private String username;
    @Value("${spring.rabbitmq.password}")
    private String password;

    /** 指定消息交换机，他指定消息按什么规则，路由到那个队列 */
    public static final String EXCHANGE_DEFAULT_SEVER = "EXCHANGE_DEFAULT_SEVER";
    public static final String EXCHANGE_REDIS_RESOURCE_SERVER = "EXCHANGE_REDIS_RESOURCE_SERVER";
    public static final String EXCHANGE_REDIS_DB_SERVER = "EXCHANGE_REDIS_DB_SERVER";
    public static final String EXCHANGE_MAIL_SERVER = "EXCHANGE_MAIL_SERVER";


    /** 消息队列，每个消息都会被一个或者是多个消息队列消费【取决于交换机的类型】 */
    public static final String QUEUE_DEFAULT_SERVER = "QUEUE_DEFAULT_SERVER";
    public static final String QUEUE_REDIS_RESOURCE_SERVER = "QUEUE_REDIS_RESOURCE_SERVER";
    public static final String QUEUE_REDIS_DB_SERVER = "QUEUE_REDIS_DB_SERVER";
    public static final String QUEUE_MAIL_SERVER = "QUEUE_MAIL_SERVER";

    /** 路由，将交换机于消息队列绑定起来，就可以使用该交换机发送消息到该队列中 */
    public static final String ROUTINGKEY_DEAULT_SERVER = "ROUTINGKEY_DEAULT_SERVER";
    public static final String ROUTINGKEY_REDIS_RESOURCE_SERVER = "ROUTINGKEY_REDIS_RESOURCE_SERVER";
    public static final String ROUTINGKEY_REDIS_DB_SERVER = "ROUTINGKEY_REDIS_DB_SERVER";
    public static final String ROUTINGKEY_MAIL_SERVER = "ROUTINGKEY_MAIL_SERVER";


    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(host, port);
        cachingConnectionFactory.setUsername(username);
        cachingConnectionFactory.setPassword(password);
        cachingConnectionFactory.setVirtualHost("/");
        cachingConnectionFactory.setPublisherConfirms(true);
        return cachingConnectionFactory;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)  //必须是prototype类型(因为要设置回调类)
    public RabbitTemplate rabbitTemplate(){
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        return template;
    }

    /** 设置交换机类型，配置默认交换机 */
    @Bean
    public DirectExchange defaultExchange(){
        return new DirectExchange(EXCHANGE_DEFAULT_SEVER);
    }

    /** 配置redis专用交换机 【资源】*/
    @Bean
   public DirectExchange redisResourceExchange(){
        return new DirectExchange(EXCHANGE_REDIS_RESOURCE_SERVER);
    }

    /** 配置redis专用交换机 【db】*/
    @Bean
    public DirectExchange redisDBExchange(){
        return new DirectExchange(EXCHANGE_REDIS_DB_SERVER);
    }

    /** 处理邮件请求的交换机 */
    @Bean
    public DirectExchange mailExchange(){
        return new DirectExchange(EXCHANGE_MAIL_SERVER);
    }


//    //配置fanout_exchange【广播】
//    @Bean
//    FanoutExchange fanoutExchange() {
//        return new FanoutExchange(RabbitConfig.EXCHANGE_DEFAULT_SEVER);
//    }
//    @Bean
//    public Binding bindA(){
//        return BindingBuilder.bind(queueDefault()).to(fanoutExchange());
//    }
//    @Bean
//    public Binding bindB(){
//        return BindingBuilder.bind(queueRedis()).to(fanoutExchange());
//    }
//    //这样配置之后，queueDefault和queueRedis这两个队列都能收到发送给fanoutExchange交换机的消息


    /** 默认队列 */
    @Bean
    public Queue queueDefault(){
        return new Queue(QUEUE_DEFAULT_SERVER, true); // true：持久化
    }
    /** redis队列 【资源】*/
    @Bean
    public Queue queueRedisResource(){
        return new Queue(QUEUE_REDIS_RESOURCE_SERVER, true);
    }
    /** redis队列 【db】*/
    @Bean
    public Queue queueRedisDB(){
        return new Queue(QUEUE_REDIS_DB_SERVER, true);
    }

    /** mail队列 */
    @Bean
    public Queue queueMail(){
        return new Queue(QUEUE_MAIL_SERVER, true);
    }

    /** 将交换机和队列绑定 */
    @Bean
    public Binding binding(){
        // 将默认队列和默认交换机通过默认路由绑定
        return BindingBuilder.bind(queueDefault()).to(defaultExchange()).with(ROUTINGKEY_DEAULT_SERVER);
    }
    /** 绑定redis交换机和redis队列 【资源】*/
    @Bean
    public Binding bingRedisResource(){
        return BindingBuilder.bind(queueRedisResource()).to(redisResourceExchange()).with(ROUTINGKEY_REDIS_RESOURCE_SERVER);
    }
    /** 绑定redis交换机和redis队列 【DB】*/
    @Bean
    public Binding bingRedisDB(){
        return BindingBuilder.bind(queueRedisDB()).to(redisDBExchange()).with(ROUTINGKEY_REDIS_DB_SERVER);
    }

    /** 绑定mail交换机和mail队列 */
    @Bean
    public Binding bingMail(){
        return BindingBuilder.bind(queueMail()).to(mailExchange()).with(ROUTINGKEY_MAIL_SERVER);
    }

    /* 可以配置绑定多个队列 */
//    @Bean
//    public Binding bindingB(){
//        return BindingBuilder.bind(queueB()).to(defaultExchange()).with(RabbitConfig.ROUTINGKEY_B);
//    }



}
